package cn.buk.qms.task;

import cn.buk.common.util.DateUtil;
import cn.buk.qms.service.*;
import cn.buk.tms.bill.service.BillCheckService;
import cn.buk.tms.car.service.RentalCarService;
import cn.buk.tms.flight.service.*;
import cn.buk.tms.vas.service.VasOrderService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;


/**
 * 定时任务
 *
 * @author yfdai
 */
@Profile({"prod"})
@Component
public class ThirdTask {

  private static final int SERVER_THIRD = 3;

  private static final Logger logger = LogManager.getLogger(ThirdTask.class);

  /**
   * 当前应用所在服务器的id
   */
  private final int serverId;

  /**
   * 当前应用所属的拥有者在数据库中对应的企业id
   */
  private final int ownerId;

  private String getAgentName() {
    return "system-" + serverId;
  }

  private final BillService billService;
  private final BillCheckService billCheckService;
  private final FlightOrderService flightOrderService;
  private final FlightChangeOrderService changeOrderService;
  private final OrderCheckService orderCheckService;
  private final FlightRefundOrderService refundOrderService;
  private final RentalCarService rentalCarService;
  private final VasOrderService vasOrderService;
  private final ReportService reportService;
  private final EnterpriseService enterpriseService;

  private final EtermService etermService;
  private final FlightCharterService flightCharterService;

  private final AutoRefundService autoRefundService;
  private final AutoChangeService autoChangeService;

  private final FlightOrderCheckService flightOrderCheckService;

  @Autowired
  public ThirdTask(@Value("${server_id}") int serverId,
                   @Value("${owner_enterprise_id}") int ownerId,
                   BillService billService,
                   BillCheckService billCheckService,
                   FlightOrderService flightOrderService,
                   FlightChangeOrderService changeOrderService,
                   FlightRefundOrderService refundOrderService,
                   OrderCheckService orderCheckService,
                   VasOrderService vasOrderService,
                   RentalCarService rentalCarService,
                   ReportService reportService,
                   EnterpriseService enterpriseService,
                   EtermService etermService,
                   FlightCharterService flightCharterService,
                   AutoRefundService autoRefundService,
                   AutoChangeService autoChangeService,
                   FlightOrderCheckService flightOrderCheckService
                   ) {
    this.serverId = serverId;
    this.ownerId = ownerId;
    this.billService = billService;
    this.billCheckService = billCheckService;
    this.flightOrderService = flightOrderService;
    this.changeOrderService = changeOrderService;
    this.refundOrderService = refundOrderService;
    this.vasOrderService = vasOrderService;
    this.rentalCarService = rentalCarService;
    this.reportService = reportService;
    this.enterpriseService = enterpriseService;
    this.etermService = etermService;
    this.flightCharterService = flightCharterService;

    this.autoRefundService = autoRefundService;
    this.autoChangeService = autoChangeService;

    this.orderCheckService = orderCheckService;
    this.flightOrderCheckService = flightOrderCheckService;
  }

  /**
   * 定时禁用近半年没有采购记录的企业客户
   */
  @Async
  @Scheduled(cron = "0 0 23 * * *")
  public void autoDisableCustomers() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    reportService.autoDisableCustomers(this.ownerId, 200, getAgentName());
  }


  /**
   * 每5分钟执行一次
   */
  @Async
  @Scheduled(cron = "0 0/5 * * * *")
  public void checkPerFiveMinutes() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    final long start = System.currentTimeMillis();

    try {
      // 检查需要提交到VAAS的第三方订单
      vasOrderService.checkVaasOrders(this.ownerId, getAgentName());
    } catch (Exception ex) {
      logger.info(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      //查找一次需要自动分配审批人的订单
      flightOrderService.checkFlightOrderNeedApprover(ownerId, getAgentName());
      rentalCarService.checkRentalCarOrderNeedApprover(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      orderCheckService.checkChangeOrderMobile(ownerId, getAgentName());
      orderCheckService.checkRefundOrderMobile(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      //查找一次需要校验是否违反企业差旅规定的订单
      flightOrderService.checkFlightOrderMeetPolicy(ownerId, getAgentName());
      rentalCarService.checkRentalCarOrderMeetPolicy(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      //查找一次需要需要自动取消的机票订单
      flightOrderService.checkFlightOrderStatus(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      orderCheckService.checkFlightOrderAirportName(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      orderCheckService.checkRefundOrderSupplier(ownerId, getAgentName());
      orderCheckService.checkChangeOrderSupplier(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      billCheckService.checkBillSupplier(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    var elapsed = System.currentTimeMillis() - start;
    logger.info("checkPerFiveMinutes elapsed time: {}.", elapsed);
  }


  @Async
  @Scheduled(cron = "0 0 3 * * *")
  public void refreshSupplierFrequency() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    final long start = System.currentTimeMillis();
    enterpriseService.refreshSupplierFrequency();
  }

  /**
   * 每30秒
   */
  @Async
  @Scheduled(cron = "0/30 * * * * *")
  public void checkPerHalfMinute() {
    if (serverId != SERVER_THIRD) {
      return;
    }
    final long start = System.currentTimeMillis();
    try {
      //查找一次需要自动生成编码和验价的
      flightOrderCheckService.checkPriceOfFlightOrders(ownerId, getAgentName());
      etermService.checkPriceOfChangeOrders(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      //南航NDC自动退票
      autoRefundService.checkFlightRefundOrder(this.ownerId, getAgentName());

      //南航NDC自动改签的
      autoChangeService.checkFlightChangeOrder(this.ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      //定时去查找FD
      etermService.checkFd(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    var elapsed = System.currentTimeMillis() - start;
    logger.info("checkPerHalfMinute elapsed time: {}.", elapsed);
  }

  /**
   * 每分钟
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkPerMinute() {
    if (serverId != SERVER_THIRD) {
      return;
    }
    final long start = System.currentTimeMillis();
    try {
      //查找一次需要发送通知的机票订单(客户自助下单的，通知后台客服）
      flightOrderService.checkFlightOrderNotifyStatus(ownerId, getAgentName());

    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }
    try {
      //去刷新刚开完票的机票订单的PNR内容
      flightOrderService.refreshFlightOrderPnrDetail(ownerId, getAgentName());
      changeOrderService.refreshChangeOrderPnrDetail(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    var elapsed = System.currentTimeMillis() - start;
    logger.info("checkPerMinute elapsed time: {}.", elapsed);
  }

  /**
   * 每10分钟去刷新刚开完票的机票订单的DETR内容
   */
  @Async
  @Scheduled(cron = "0 0/10 * * * *")
  public void checkPerFifteenMinutes() {
    if (serverId != SERVER_THIRD) {
      return;
    }
    final long start = System.currentTimeMillis();

    try {
      refundOrderService.refreshRefundOrderDetrDetail(ownerId, getAgentName());
      changeOrderService.refreshChangeOrderDetrDetail(ownerId, getAgentName());
      flightOrderService.refreshFlightOrderDetrDetail(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    try {
      //检查机票订单的显示状态
      flightOrderService.checkFlightOrderShowStatus(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }

    var elapsed = System.currentTimeMillis() - start;
    logger.info("checkPerFifteenMinutes elapsed time: {}.", elapsed);
  }

  /**
   * 每天重新检查未使用状态，但起飞日期已过的国内机票
   */
  @Async
  @Scheduled(cron = "0 0/30 * * * *")
  public void checkPerHalfHour() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    final long start = System.currentTimeMillis();
    try {
      flightOrderService.recheckFlightOrderDetrInfo(ownerId, getAgentName());
      changeOrderService.recheckChangeOrderDetrInfo(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }


    var elapsed = System.currentTimeMillis() - start;
    logger.info("checkPerHalfHour elapsed time: {}.", elapsed);
  }

  /**
   * 每天检查机票业务规则
   */
  @Async
  @Scheduled(cron = "0 0 3 * * *")
  public void validateFlightBusinessRule() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      flightOrderService.validateFlightBusinessRule(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }
  }

  /**
   * 定时清Q
   */
  @Async
  @Scheduled(cron = "0 0/15 6-23 * * *")
  public void qt() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      etermService.qt(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }
  }

  /**
   * 每天8点下载TPR并自动审核
   */
  @Async
  @Scheduled(cron = "0 15 6,9,12,18 * * *")
  public void autoDownloadTprAndReview() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      //1. 导入昨日的TPR
      //国内
      flightCharterService.importTprInfoByDate(this.ownerId, this.getAgentName(), 1, 0, DateUtil.getYesterday());
      //国际
      flightCharterService.importTprInfoByDate(this.ownerId, this.getAgentName(), 2, 1, DateUtil.getYesterday());
      //2. 自动审核
      billService.autoReviewBillInfoByTask(this.ownerId, this.getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }
  }

  /**
   * 定时生成每日审核任务
   */
  @Async
  @Scheduled(cron = "0 0 5 * * *")
  public void createDailyAuditTask() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      enterpriseService.createDailyAuditTask(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      ex.printStackTrace();
    }
  }

  @Async
  @Scheduled(cron = "0 0 0/8 * * *")
  public void syncBillInfoAirlines() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    billCheckService.syncBillAirlines();
    billCheckService.checkFlightOrderImportedStatus(getAgentName());
  }
}
